// SPDX-License-Identifier: GPL-2.0
#include <linux/list.h>
#include "lookup_optimize.h"

/* get kernel module list */
extern struct list_head *get_kernel_modules(void);

int object_module_on_each_symbol(const char *objname, int (*fn)(void *,
				 const char *, struct module *,
				 unsigned long), void *data)
{
	struct module *mod;
	struct list_head *modules = get_kernel_modules();
	unsigned int i;
	int ret;
	struct mod_kallsyms *kallsyms;
	int found = 0;

	list_for_each_entry(mod, modules, list) {
		if (mod->state == MODULE_STATE_UNFORMED)
			continue;

		if (!strcmp(objname, mod->name)) {
			found = 1;
			break;
		}
	}
	if (!found)
		return -EINVAL;

	/* We hold module_mutex: no need for rcu_dereference_sched */
	kallsyms = mod->kallsyms;

	for (i = 0; i < kallsyms->num_symtab; i++) {
		ret = fn(data, kallsyms->strtab + kallsyms->symtab[i].st_name,
			 mod, kallsyms->symtab[i].st_value);
		if (ret != 0)
			return ret;
	}

	return 0;
}

